﻿#include "SpriteCore.h"



Sprite::SpriteCore::SpriteCore( HINSTANCE hInstace ):m_hInstance(hInstace)
{
	m_pCMainWindow = new SpriteWindows(hInstace);	
	g_pCD3d =	0;
	m_pCMainTimer = NULL;
}

Sprite::SpriteCore::SpriteCore( HINSTANCE hInstace,int width,int height,std::wstring title ):m_hInstance(hInstace)
{
	m_pCMainWindow = new SpriteWindows(hInstace,width,height,title);
	g_pCD3d =	0;
	m_pCMainTimer = NULL;
}


Sprite::SpriteCore::~SpriteCore(void)
{
	Delete(m_pCMainWindow);
	Delete(g_pCD3d);

}

HRESULT Sprite::SpriteCore::init()
{
		m_pCMainTimer = new SpriteTimer();
	iniWindows();
	initD3D();

	return S_OK;
}

int Sprite::SpriteCore::run()
{
	MSG msg ={0};

	ZeroMemory(&msg,sizeof(MSG));

	while(msg.message != WM_QUIT)
	{
		// If there are Window messages then process them.
		if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}	
		else
		{

			m_pCMainTimer->tick();

			if( !m_pCMainTimer->isStopped() )
				updateScene(m_pCMainTimer->getDeltaTime());	
			else
				Sleep(50);

			drawScene();
		}
	}
	return (int)msg.wParam;
}

HRESULT Sprite::SpriteCore::initD3D()
{
	//默认是通过DX10的初始化，以后可以扩充DX9或者DX11
	HRESULT hr = S_OK;
	g_pCD3d = new SpriteD3D10();
	hr = g_pCD3d->initD3D(m_HMainWnd,m_pCMainWindow->getWidth(),m_pCMainWindow->getHeight());
	g_pCD3d->onResize();
	m_pCMainCamera = new SpriteCamera();
	return	hr;
}

HRESULT Sprite::SpriteCore::iniWindows()
{
	HRESULT hr = m_pCMainWindow->initWindow();
	m_HMainWnd = m_pCMainWindow->getHWND();
	return hr;
}

void Sprite::SpriteCore::updateScene(float dt)
{	

}

void Sprite::SpriteCore::drawScene()
{
	//	m_pCD3D->begin();
	// We specify DT_NOCLIP, so we do not care about width/height of the rect.
	//	RECT R = {5, 5, 0, 0};

	//m_pCD3D->end();
	/*m_pCD3D->begin();
	font->draw(mFrameStats);
	m_pCD3D->end();*/

}

LRESULT Sprite::SpriteCore::CoreMsgProc( UINT msg,WPARAM wParam,LPARAM lParam )
{
	switch( msg )
	{		
		// WM_ACTIVATE is sent when the window is activated or deactivated.  
		// We pause the game when the window is deactivated and unpause it 
		// when it becomes active.  
	case WM_ACTIVATE:
		if( LOWORD(wParam) == WA_INACTIVE )
		{
			m_pCMainTimer->setStopped(true);
			m_pCMainTimer->stop();
		}
		else
		{
			m_pCMainTimer->setStopped(false);
			m_pCMainTimer->start();
		}
		return 0;
		// WM_SIZE is sent when the user resizes the window.  
	case WM_SIZE:
		// Save the new client area dimensions.
		  m_nWidth  = LOWORD(lParam);
		  m_nHeight = HIWORD(lParam);
		if( g_pCD3d )
		{
			if( wParam == SIZE_MINIMIZED )
			{
				m_pCMainTimer->setStopped(true);
				m_pCMainWindow->setMix(true);
				m_pCMainWindow->setMax(false);
			}
			else if( wParam == SIZE_MAXIMIZED )
			{
				m_pCMainTimer->setStopped(false);
				m_pCMainWindow->setMix(false);
				m_pCMainWindow->setMax(true);
				g_pCD3d->onResize(m_nWidth,m_nHeight);
			}
			else if( wParam == SIZE_RESTORED )
			{

				// Restoring from minimized state?
				if( m_pCMainWindow->isMix() )
				{
					m_pCMainTimer->setStopped(false);
					m_pCMainWindow->setMix(false);					
					g_pCD3d->onResize(m_nWidth,m_nHeight);
				}

				// Restoring from maximized state?
				else if( m_pCMainWindow->isMax() )
				{
					m_pCMainTimer->setStopped(false);
					m_pCMainWindow->setMax(false);
					g_pCD3d->onResize(m_nWidth,m_nHeight);
				}
				else if( m_pCMainWindow->isResizing() )
				{
					// If user is dragging the resize bars, we do not resize 
					// the buffers here because as the user continuously 
					// drags the resize bars, a stream of WM_SIZE messages are
					// sent to the window, and it would be pointless (and slow)
					// to resize for each WM_SIZE message received from dragging
					// the resize bars.  So instead, we reset after the user is 
					// done resizing the window and releases the resize bars, which 
					// sends a WM_EXITSIZEMOVE message.
				}
				else // API call such as SetWindowPos or mSwapChain->SetFullscreenState.
				{
					g_pCD3d->onResize(m_nWidth,m_nHeight);
				}
			}
		}
		return 0;
	case WM_ENTERSIZEMOVE:
		m_pCMainTimer->setStopped(true);
		m_pCMainWindow->setResizing(true);
			m_pCMainTimer->stop();
		return 0;

		// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
		// Here we reset everything based on the new window dimensions.
	case WM_EXITSIZEMOVE:
		m_pCMainTimer->setStopped(false);
		m_pCMainWindow->setResizing(false);
		m_pCMainTimer->start();
		g_pCD3d->onResize();
		return 0;		

		// The WM_MENUCHAR message is sent when a menu is active and the user presses 
		// a key that does not correspond to any mnemonic or accelerator key. 
	case WM_MENUCHAR:
		// Don't beep when we alt-enter.
		return MAKELRESULT(0, MNC_CLOSE);

		// Catch this message so to prevent the window from becoming too small.
	case WM_GETMINMAXINFO:
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 200;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 200; 
		return 0;
	}
	return DefWindowProc(m_HMainWnd, msg, wParam, lParam);
}

Sprite::SpriteCore* Sprite::SpriteCore::Instance()
{

	return m_pCCore;
}

Sprite::SpriteCore * Sprite::SpriteCore::CreateInstace( HINSTANCE hInstace )
{
	if (m_pCCore!=NULL)
	{
		Delete(m_pCCore);
	}
	m_pCCore  =  new SpriteCore(hInstace);
	return m_pCCore;
}

Sprite::SpriteCore* Sprite::SpriteCore::CreateInstace( HINSTANCE hInstace,int width,int height,std::wstring title )
{
	if (m_pCCore!=NULL)
	{
		Delete(m_pCCore);
	}
	m_pCCore  =  new SpriteCore(hInstace,width,height,title);
	return m_pCCore;
}

Sprite::SpriteCore* Sprite::SpriteCore::m_pCCore = NULL;